package labox.innovation.db;

import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.List;

import javolution.util.FastList;
import labox.innovation.config.Config;
import labox.innovation.db.core.HeapByteBuffer;
import labox.innovation.db.core.SqlData;
import labox.innovation.db.manager.DBConnetionStateManager;
import labox.innovation.db.proxy.ConnectionProxy;
import labox.innovation.db.proxy.PreparedStatementProxy;
import labox.innovation.db.util.DbUtil;
import labox.innovation.db.util.SqlDataIdFactory;
import labox.innovation.gameserver.ThreadPoolManager;
import labox.innovation.gameserver.model.FriendInfo;
import labox.innovation.gameserver.model.actor.instance.FuzePcInstance;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class PlayFriends {
	public static final Logger _log = LoggerFactory.getLogger(PlayFriends.class.getName());
	/**
	 * ��������б�
	 */
	private static final String SAVE_FRIEND_LIST = "REPLACE INTO character_friends (charId, details,hasfriends) VALUES (?, ?, ?)";
	private static final String LOAD_CHARACTERS_FRIENDS = "SELECT details,hasfriends FROM character_friends WHERE charId=? AND relation=0";
	private static final String LOAD_FRIEND_INFO = "select charId,level,classid,char_name from characters where charId=?";
	private static final String UPDATE_FRIENDS_LIST = "update character_friends set hasfriends=REPLACE(hasfriends,?,',') where charId=?";
	/**
	 * ɾ����Ѽ�¼
	 */
	public static final String PHYSICAL_DELETE_CHARACTER_FRIENDS_BY_ID="delete from character_friends where charId=?";
	/**
	 * ������Һ����б�
	 * 
	 * @param requestor
	 *            ���
	 * @param friendList
	 *            �����б�
	 * @return
	 * @throws SQLException 
	 */
	public static void updateplayer_Friends(FuzePcInstance requestor, FastList<FriendInfo> friendList) {
		HeapByteBuffer _buf = HeapByteBuffer.newInstance();
		StringBuffer st = new StringBuffer();
		List<Long> hashfriends = requestor.getFriendInstance().getHeroesId();
		if (hashfriends != null) {
			for (long hashfriendId : hashfriends) {
				st.append(hashfriendId + ",");
			}
		}
		_buf.clear();
		ConnectionProxy con = null;
		PreparedStatementProxy ptmt = null;
		Object[] params = null;
		SqlData data = null;
		// ���BUFF
		int size = friendList.size();
		_buf.writeInt(size);
		for (FriendInfo friendInfo : friendList) {
			_buf.writeLong(friendInfo.getFriendId());
		}
		_buf.flip();

		try {
			if (!DBConnetionStateManager.getDbState()) {
				params = new Object[] { requestor.getObjectId(), _buf, st.length() > 0 ? st.toString() : "," };
				data = new SqlData(SqlDataIdFactory.createSqlId("character_friends", requestor.getObjectId()), SAVE_FRIEND_LIST, params);
				DBConnetionStateManager.addDbTask(data);
			} else {
				con = ConnectionProxy.newInstance();
				if (con != null)
					ptmt = con.prepareStatement(SAVE_FRIEND_LIST);
				// ����Ƿ������д����ݿ�
				if (DbUtil.isDbNormal(DBConnetionStateManager.getDbState(), con, ptmt)) {
					ptmt.setLong(1, requestor.getObjectId());
					ptmt.setBinaryStream(2, _buf, _buf.limit());
					ptmt.setString(3, st.length() > 0 ? st.toString() : null);
					int rs = ptmt.executeUpdate();
					if (rs != PreparedStatementProxy.NETWORKDISCONNECTION) {
						HeapByteBuffer.recycle(_buf);
					} else {
						params = new Object[] { requestor.getObjectId(), _buf, st.length() > 0 ? st.toString() : "," };
						data = new SqlData(SqlDataIdFactory.createSqlId("character_friends", requestor.getObjectId()), SAVE_FRIEND_LIST, params);
						DBConnetionStateManager.addDbTask(data);
					}
				}else{
					params = new Object[] { requestor.getObjectId(), _buf, st.length() > 0 ? st.toString() : "," };
					data = new SqlData(SqlDataIdFactory.createSqlId("character_friends", requestor.getObjectId()), SAVE_FRIEND_LIST, params);
					DBConnetionStateManager.addDbTask(data);
				
				}
			}
		} catch (SQLException e) {
			_log.error("save character friends to db error", Config.SERVER_ID, e);
		} finally {
			if (ptmt != null)
				ptmt.close();
			if (con != null)
				con.close();
		}

	}

	/**
	 * ������Һ����б� _friendList heroesId
	 * 
	 * @param friendList
	 *            �����б�
	 * @param player
	 *            ���
	 */
	public static void restoreFriendList(FastList<FriendInfo> friendList, FuzePcInstance player) {
		HeapByteBuffer _buf = HeapByteBuffer.newInstance();
		_buf.clear();
		ConnectionProxy con = null;
		PreparedStatementProxy ptmt = null;
		ResultSet rs = null;
		PreparedStatementProxy ptmt1 = null;
		ResultSet rs1 = null;
		try {
			if (!DBConnetionStateManager.getDbState())
				return;
			con = ConnectionProxy.newInstance();
			if (con != null)
				ptmt = con.prepareStatement(LOAD_CHARACTERS_FRIENDS);
			if (!DbUtil.isDbNormal(DBConnetionStateManager.getDbState(), con, ptmt))
				return;
			ptmt.setLong(1, player.getObjectId());
			rs = ptmt.executeQuery();
			byte[] _bytes;
			friendList.clear();
			String hasfriends;
			FriendInfo friendInfo;
			while (rs.next()) {
				_bytes = rs.getBytes("details");
				_buf.write(_bytes, 0, _bytes.length);
				hasfriends = rs.getString("hasfriends");
				if (hasfriends != null) {
					String[] _hasfriends = hasfriends.split(",");
					player.getFriendInstance().clearheroesId();
					for (int i = 0; i < _hasfriends.length; i++) {
						String _hasfriendId = _hasfriends[i];
						if (_hasfriendId != null && !_hasfriendId.equals(""))
							player.getFriendInstance().addheroesId(Long.parseLong(_hasfriendId));
					}
				}
				_buf.flip();
				ptmt1 = con.prepareStatement(LOAD_FRIEND_INFO);
				int size = _buf.readInt();
				for (int i = 0; i < size; i++) {
					long friendId = _buf.readLong();
					ptmt1.setLong(1, friendId);
					rs1 = ptmt1.executeQuery();
					while (rs1.next()) {
						friendInfo = new FriendInfo(player.getObjectId(), rs1.getLong(1), rs1.getInt(2), rs1.getInt(3), 1, rs1.getString(4));
						player.getFriendInstance().addFriend(friendInfo);
					}
				}
				_buf.clear();
			}
		} catch (SQLException e) {
			_log.warn("Error found in restoreFriendList" + e);
		} finally {
			HeapByteBuffer.recycle(_buf);
			try {
				if (rs != null)
					rs.close();
				if (rs1 != null)
					rs1.close();
			} catch (SQLException e1) {
				e1.printStackTrace();
			}
			if (ptmt1 != null)
				ptmt1.close();
			if (ptmt != null)
				ptmt.close();
			if (con != null)
				con.close();
		}
	}

	/**
	 * ɾ��Ӻ����б�
	 * 
	 * @param id
	 *            ���Ӻ���ID
	 * @param activeChar
	 *            ���
	 */
	public static void deleteplayer_Friends(long id, FuzePcInstance activeChar) {
		ThreadPoolManager.getInstance().execute(new DeleteFriendTask(id, activeChar));
	}

	public static class DeleteFriendTask implements Runnable {
		private long id;
		private FuzePcInstance _activeChar;

		public DeleteFriendTask(long id, FuzePcInstance activeChar) {
			this.id = id;
			this._activeChar = activeChar;

		}

		@Override
		public void run() {
			ConnectionProxy con = null;
			PreparedStatementProxy ptmt = null;
			Object params = null;
			SqlData data = null;
			try {
				if (!DBConnetionStateManager.getDbState()) {
					params = new Object[] { _activeChar.getObjectId() + ",", id };
					data = new SqlData(SqlDataIdFactory.createSqlId("character_friends_delete" + id, _activeChar.getObjectId()), UPDATE_FRIENDS_LIST, params);
					DBConnetionStateManager.addDbTask(data);
				} else {
					con = ConnectionProxy.newInstance();
					if (con != null)
						ptmt = con.prepareStatement(UPDATE_FRIENDS_LIST);
					if (DbUtil.isDbNormal(DBConnetionStateManager.getDbState(), con, ptmt)) {
						ptmt.setString(1, _activeChar.getObjectId()+ ",");
						ptmt.setLong(2, id);
						int rs = ptmt.executeUpdate();
						if (rs == PreparedStatementProxy.NETWORKDISCONNECTION) {
							params = new Object[] { _activeChar.getObjectId() + ",", id };
							data = new SqlData(SqlDataIdFactory.createSqlId("character_friends_delete" + id, _activeChar.getObjectId()), UPDATE_FRIENDS_LIST, params);
							DBConnetionStateManager.addDbTask(data);
						}
					}
				}

			} catch (SQLException e) {
				_log.error("delete friend to db error", Config.SERVER_ID, e);
				e.printStackTrace();
			} finally {
				if (ptmt != null) {
					ptmt.close();
				}
				if (con != null)
					con.close();
			}
		}
	}
}
